package com.weasel.im.server;

import com.weasel.im.common.manager.IMSessionManager;
import com.weasel.im.common.manager.LeaveMessageCacheManager;
import com.weasel.im.common.manager.UserSessionRelationManager;
import com.weasel.im.common.cache.LeaveMessageCache;
import com.weasel.im.server.exception.IMSessionManagerNullException;
import com.weasel.im.server.exception.UserSessionRelationManagerNullException;
import com.weasel.im.server.initializer.JettyIMServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Dylan on 2015/11/27.
 */
public final class IMServerLauncher {

    private final Logger logger = LoggerFactory.getLogger(IMServerLauncher.class);

    private IMSessionManager sessionManager = null;
    private UserSessionRelationManager relationManager = null;
    private LeaveMessageCacheManager leaveMessageCacheManager = null;

    private int port = 8080;

    public static IMServerLauncher listen(int _port){

        IMServerLauncher launcher = new IMServerLauncher();
        launcher.port = _port;
        return  launcher;
    }

    public IMServerLauncher withSessionManager(IMSessionManager _sessionManager){
        this.sessionManager = _sessionManager;
        return this;
    }

    public IMServerLauncher withUserSessionRelationManager(UserSessionRelationManager _relationManager){
        this.relationManager = _relationManager;
        return this;
    }

    public IMServerLauncher withMessageCacheManager(LeaveMessageCacheManager _leaveMessageCacheManager){
        this.leaveMessageCacheManager = _leaveMessageCacheManager;
        return this;
    }

    public void launch(){

        verifyManager();   //验证manager

        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boss,worker)
                 .channel(NioServerSocketChannel.class)
                 .childHandler(new JettyIMServerInitializer(sessionManager,relationManager,leaveMessageCacheManager))
                 .option(ChannelOption.SO_BACKLOG, 128)
                 .childOption(ChannelOption.SO_KEEPALIVE, true);

        logger.info("IM服务器启动");
        try {
            ChannelFuture future = bootstrap.bind(port)
                                            .sync();

            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
            logger.info("IM服务器关闭");
        }
    }

    /**
     *
     */
    private void verifyManager(){

        if(sessionManager == null ){
            throw new IMSessionManagerNullException("please with a session manager");
        }
        if(relationManager == null){
            throw new UserSessionRelationManagerNullException("please with a user and session relation manager");
        }
        if(leaveMessageCacheManager == null){
            logger.warn("message cache is null,will can not leave message to other people");
        }
    }
    private IMServerLauncher(){};
}
